package test

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"fmt"

	rsautil "idoone.cc/idoonego/crypto/rsa"
)

var pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCt/gLLdVKhiRWM4YRTh1vjfdh0UaILNg1rmhgYAapWPplpB3wnKEnpNYhK6ZCABCXjn906t9u4BVxFZhYRncYAt2USeXOqENKTxsn+G2miGraTAbkyL914ZVUVy6h+YnUMZwEjnZh+QJ/tvXUgvi9BvSR+ahjtBE1mRW24l+r3RwIDAQAB"
var prikey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAK3+Ast1UqGJFYzhhFOHW+N92HRRogs2DWuaGBgBqlY+mWkHfCcoSek1iErpkIAEJeOf3Tq327gFXEVmFhGdxgC3ZRJ5c6oQ0pPGyf4baaIatpMBuTIv3XhlVRXLqH5idQxnASOdmH5An+29dSC+L0G9JH5qGO0ETWZFbbiX6vdHAgMBAAECgYAW6rYDhlhz3lJwU+PR/KoltJWl/HqTb3MlEQ7LWqzM30Hli47WuX/Cr8Jb25ekxOcYrB2/digCfPJCUcfmWhmSFvv+LeZxwQz56aWcXFzMkHRWty2GVoAv4z4iSiEwTH3TQrCINX08x2sb44QGYwTXFdohScxVdCaHCVADqadMgQJBANWuAoMeYHRGfQYxmJtNVQh3Mplcs4Pci6ANCBlzOBYVQoT/54Xapo8iotvCmWmaMtE8zwf1rD+N2djXEjO+bskCQQDQc8P74+ObKU1cuW8rYCEF4ijJCUqX4WrjtYCFQ3Af01cJCioesp/Mxvs0Q+kbyD5LAkiI4Y4ZkW0cbIIKo+2PAkEAkAEIcmMbb+E9StpL1YYFY4IpWI/P73LHqmJ97eDnkIJdZRKtblkP3PDjvqTkDPY9fyOzBtM7dU1c3jT7cGHLeQJBANAaMpc/DFQz6JLgYVapUm6AOP1ytDBqj36jDZp9F+v93g8dQa2B4DzcjZ7BCXB9+YqCzg0xON7Xq1lMDos22osCQQCVQhh20ECrk2QV0U+gAOgfXkIP6Jj12OSH/xeWcz9hT547OtQ4aG9hw31g+wtBOZFTR4AZ/UfWSJon+zAlEruN"

func TestRSAPem() {
	publicKey := "-----BEGIN PUBLIC KEY-----\r\n" + pubkey + "\r\n-----END PUBLIC KEY-----"
	privateKey := "-----BEGIN RSA PRIVATE KEY-----\r\n" + prikey + "\r\n-----END RSA PRIVATE KEY-----"
	raw := "hello"
	enc, err := rsaEncrypt([]byte(raw), []byte(publicKey))
	encb64 := base64.StdEncoding.EncodeToString(enc)
	enc, err = base64.StdEncoding.DecodeString(encb64)
	fmt.Println("err:", err, " enc:", encb64)
	dec, err := rsaDecrypt(enc, []byte(privateKey))
	fmt.Println("err:", err, " dec:", string(dec))

	b64 := "JOAF2kgzCX4vyvUAUEfrjupG63l0g6M8Q3tSL2sWglOW4Ciyq3Q5+Zpppl2lvWgO33u5pxQ0kdMqYDqCXGlRq45B22ib0XzCCiazBwMiJwJytaBo75EB9i800sGuntUwBwX/RPSZs/6XcpTxc/qnyJLlPHvrSg1SV/covUEMQfc="
	enc, err = base64.StdEncoding.DecodeString(b64)
	dec, err = rsaDecrypt(enc, []byte(privateKey))
	fmt.Println("err:", err, " dec:", string(dec))
}

func TestRSA() {
	raw := "hello"
	enc, err := rsautil.ECBPKCS1PaddingEncrypt([]byte(raw), pubkey)
	encb64 := base64.StdEncoding.EncodeToString(enc)
	enc, err = base64.StdEncoding.DecodeString(encb64)
	fmt.Println("err:", err, " enc:", encb64)
	dec, err := rsautil.ECBPKCS1PaddingDecrypt(enc, prikey)
	fmt.Println("err:", err, " dec:", string(dec))

	b64 := "JOAF2kgzCX4vyvUAUEfrjupG63l0g6M8Q3tSL2sWglOW4Ciyq3Q5+Zpppl2lvWgO33u5pxQ0kdMqYDqCXGlRq45B22ib0XzCCiazBwMiJwJytaBo75EB9i800sGuntUwBwX/RPSZs/6XcpTxc/qnyJLlPHvrSg1SV/covUEMQfc="
	enc, err = base64.StdEncoding.DecodeString(b64)
	dec, err = rsautil.ECBPKCS1PaddingDecrypt(enc, prikey)
	fmt.Println("err:", err, " dec:", string(dec))
}

func rsaEncrypt(origData []byte, pubKey []byte) ([]byte, error) {
	block, _ := pem.Decode(pubKey)
	if block == nil {
		return nil, errors.New("public key error")
	}
	pubI, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	pub := pubI.(*rsa.PublicKey)
	return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}

func rsaDecrypt(cipherText []byte, privKey []byte) ([]byte, error) {
	block, _ := pem.Decode(privKey)
	if block == nil {
		return nil, errors.New("private key error!")
	}
	prkI, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	priv := prkI.(*rsa.PrivateKey)
	return rsa.DecryptPKCS1v15(rand.Reader, priv, cipherText)
}
